/** 
 * \file gdscal.cu
 * \author Kyle E. Niemeyer
 * \date 10/04/2011
 *
 * Based on "dscal.f" from BLAS.
 *
 */

////////////////////////////////////////////////////////////////////////

/** gdscal scales a double precision vector with a scalar. BLAS level one.
 * uses unrolled loops for increments equal to one.
 *
 * \param[in]     n       number of elements in vector
 * \param[in]     da      scalar alpha
 * \param[in,out] dx      vector to be scaled, dimension (n-1) * |incx| + 1
 * \param[in]     incx    increment between elements of dx
 */
__device__ __inline__ void gdscal ( int n, double da, double *dx, int incx )
{
  
  if ( ( n <= 0 ) || ( incx <= 0 ) ) return;
  
  if ( incx == 1 ) {
    
    // increment equal to 1
    
    // clean-up loop
    
    uint m = n % 5;
    if ( m != 0 ) {
      
      for ( uint i = 0; i < m; ++i ) {
        dx[i] *= da;
      }
      
      if ( n < 5 ) return;
    }
    
    for ( uint i = m; i < n; i += 5 ) {
      dx[i] *= da;
      dx[i + 1] *= da;
      dx[i + 2] *= da;
      dx[i + 3] *= da;
      dx[i + 4] *= da;
    }
    
  } else {
    
    // increment not equal to 1
    
    uint nincx = n * incx;
    
    for ( uint i = 0; i < nincx; i += incx ) {
      dx[i] *= da;
    }
    
  } // end incx if

} // end gdscal